package org.wheel.plugins.starter.jdbc.pool.config;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.core.io.Resource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.*;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@RequiredArgsConstructor
public class XmlMapperLoader {

    // 直接使用 LogFactory 创建日志对象，Hutool 会自动检测项目中的日志框架（优先级：Slf4j > Log4j > Logback > JDK Logging）
    private static final Log log = LogFactory.get();

    /**
     * 缓存 XML 文件中的 SQL
     */
    private static final Map<String, String> XML_SQL = new ConcurrentHashMap<>(); // namespace.id -> sql


    public static void load(Resource[] resources) throws IOException,
            XPathExpressionException, ParserConfigurationException, SAXException {
        for (Resource res : resources) {
            Document doc = DocumentBuilderFactory.newInstance()
                    .newDocumentBuilder().parse(res.getInputStream());
            XPath xp = XPathFactory.newInstance().newXPath();

            // 编写 XPath 表达式来获取 <mapper> 根节点的 namespace 属性值
            String expression = "/mapper/@namespace";
            XPathExpression expr = xp.compile(expression);
            NodeList root = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
            if(root.getLength() > 0){
                String namespaceValue = root.item(0).getNodeValue();

                NodeList list = (NodeList) xp.evaluate("//select|//insert|//update|//delete",
                        doc, XPathConstants.NODESET);
                for (int i = 0; i < list.getLength(); i++) {
                    Element e = (Element) list.item(i);
                    String type = e.getTagName();
                    String id = e.getAttribute("id");
                    String sql = e.getTextContent().replace('\n', ' ').trim();
                    log.debug("Found SQL statement: " + type + " -> " + id + " -> " + sql);
                    XML_SQL.put(namespaceValue+"."+id+".type", type.toLowerCase());
                    XML_SQL.put(namespaceValue+"."+id, sql);
                }
            }else{
                log.debug("未找到 <mapper> 根节点命名空间（/mapper/@namespace） namespace file: {}", res.getFile().getAbsoluteFile());
            }
        }
    }

    /**
     * 获取 XML 文件中的 SQL
     * @param statementId SQL唯一ID，传入值格式：命名空间.id
     * @return XML 中定义的 SQL 语句
     */
    public static String getXmlSql(String statementId) {
        return XML_SQL.get(statementId);
    }

    /**
     * 获取 XML 文件中的 SQL 类型
     * @param statementId SQL唯一ID，传入值格式：命名空间.id
     * @return XML 中定义的 SQL 语句类型：select/insert/update/delete
     */
    public static String getXmlSqlType(String statementId) {
        return XML_SQL.get(statementId+".type");
    }



//    private final DaoConfigProperties daoConfigProperties;
//
//    private final ResourceLoader resourceLoader;

//    public List<File> loadXmlFiles() {
//        List<File> xmlFiles = new ArrayList<>();
//        String path = daoConfigProperties.getXmlPath();
//        try {
//            Resource resource = resourceLoader.getResource(path);
//            File file = resource.getFile();
//            if (file.isDirectory()) {
//                File[] files = file.listFiles((dir, name) -> name.endsWith(".xml"));
//                if (files != null) {
//                    xmlFiles.addAll(List.of(files));
//                }
//            } else if (file.exists()) {
//                xmlFiles.add(file);
//            }
//        } catch (IOException e) {
////            e.printStackTrace();
//            log.warn("加载XML文件失败：" + e.getMessage());
//        }
//        return xmlFiles;
//    }

//    private void parseXmlFile(File xmlFile) {
//        log.debug("Parsing XML file: " + xmlFile.getAbsolutePath());
////        Document document = XmlUtil.readXML(xmlFile);
//        Document document = null;
//        try {
//            document = CustomXmlUtil.readXML(xmlFile);
//        } catch (Exception e) {
////            throw new RuntimeException(e);
//            log.error("Error parsing XML file: " + xmlFile.getAbsolutePath(), e);
//        }
//        Element root = XmlUtil.getRootElement(document);
//        String namespace = root.getAttribute("namespace");
//
//        NodeList selectNodes = root.getElementsByTagName("select");
//        for (int i = 0; i < selectNodes.getLength(); i++) {
//            Element selectElement = (Element) selectNodes.item(i);
//            String id = selectElement.getAttribute("id");
//            String sql = selectElement.getTextContent();
////            System.out.println("Found select statement: " + id + " -> " + sql);
//            // 保存到内存或数据库中
//            XML_SQL.put(namespace + "." + id, sql);
//        }
//
//        NodeList insertNodes = root.getElementsByTagName("insert");
//        for (int i = 0; i < insertNodes.getLength(); i++) {
//            Element insertElement = (Element) insertNodes.item(i);
//            String id = insertElement.getAttribute("id");
//            String sql = insertElement.getTextContent();
////            System.out.println("Found insert statement: " + id + " -> " + sql);
//            // 保存到内存或数据库中
//            XML_SQL.put(namespace + "." + id, sql);
//        }
//
//        NodeList updateNodes = root.getElementsByTagName("update");
//        for (int i = 0; i < updateNodes.getLength(); i++) {
//            Element updateElement = (Element) updateNodes.item(i);
//            String id = updateElement.getAttribute("id");
//            String sql = updateElement.getTextContent();
////            System.out.println("Found update statement: " + id + " -> " + sql);
//            // 保存到内存或数据库中
//            XML_SQL.put(namespace + "." + id, sql);
//        }
//
//        NodeList deleteNodes = root.getElementsByTagName("delete");
//        for (int i = 0; i < deleteNodes.getLength(); i++) {
//            Element deleteElement = (Element) deleteNodes.item(i);
//            String id = deleteElement.getAttribute("id");
//            String sql = deleteElement.getTextContent();
////            System.out.println("Found delete statement: " + id + " -> " + sql);
//            // 保存到内存或数据库中
//            XML_SQL.put(namespace + "." + id, sql);
//        }
//    }
}